using System;
using System.Net.Http;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using System.Net;
using System.Diagnostics;
using System.IO;

namespace Update.Services
{
    public class GiteeApi
    {
        private readonly HttpClient _httpClient;
        private readonly string _owner;
        private readonly string _repo;
        private readonly string _accessToken;
        private const int MaxRetries = 3;
        private const int RetryDelayMs = 2000;

        public GiteeApi(string owner, string repo, string accessToken = null)
        {
            _httpClient = new HttpClient();
            _httpClient.DefaultRequestHeaders.Add("User-Agent", "SanmaoTools");
            _owner = owner;
            _repo = repo;
            _accessToken = accessToken;
        }

        public async Task<GiteeReleaseInfo> GetLatestReleaseAsync()
        {
            try
            {
                string url = $"https://gitee.com/api/v5/repos/{_owner}/{_repo}/releases/latest";
                if (!string.IsNullOrEmpty(_accessToken))
                {
                    url += $"?access_token={_accessToken}";
                }

                Debug.WriteLine($"正在请求 Gitee API: {url}");
                var response = await _httpClient.GetAsync(url);
                
                if (response.StatusCode == HttpStatusCode.NotFound)
                {
                    throw new Exception($"未找到仓库或发布版本。请确认仓库 {_owner}/{_repo} 存在且有发布版本。");
                }
                
                response.EnsureSuccessStatusCode();
                var content = await response.Content.ReadAsStringAsync();
                Debug.WriteLine($"Gitee API 响应: {content}");

                var options = new JsonSerializerOptions
                {
                    PropertyNameCaseInsensitive = true
                };
                
                var releaseInfo = JsonSerializer.Deserialize<GiteeReleaseInfo>(content, options);
                if (releaseInfo == null)
                {
                    throw new Exception("无法解析发布信息");
                }

                if (string.IsNullOrEmpty(releaseInfo.TagName))
                {
                    throw new Exception($"API返回的版本标签为空。API响应: {content}");
                }
                
                return releaseInfo;
            }
            catch (HttpRequestException ex)
            {
                throw new Exception($"访问Gitee API失败: {ex.Message}");
            }
            catch (JsonException ex)
            {
                throw new Exception($"解析发布信息失败: {ex.Message}");
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"获取最新发布版本失败: {ex.Message}");
                throw;
            }
        }

        public async Task<byte[]> DownloadReleaseAssetAsync(string downloadUrl, IProgress<(long current, long total)> progress = null)
        {
            int retryCount = 0;
            Exception lastException = null;

            while (retryCount < MaxRetries)
            {
                try
                {
                    if (!string.IsNullOrEmpty(_accessToken))
                    {
                        downloadUrl += (downloadUrl.Contains("?") ? "&" : "?") + $"access_token={_accessToken}";
                    }

                    using var response = await _httpClient.GetAsync(downloadUrl, HttpCompletionOption.ResponseHeadersRead);
                    response.EnsureSuccessStatusCode();

                    var totalBytes = response.Content.Headers.ContentLength ?? -1L;
                    using var contentStream = await response.Content.ReadAsStreamAsync();
                    using var memoryStream = new MemoryStream();

                    var buffer = new byte[8192];
                    var totalBytesRead = 0L;
                    int bytesRead;

                    while ((bytesRead = await contentStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
                    {
                        await memoryStream.WriteAsync(buffer, 0, bytesRead);
                        totalBytesRead += bytesRead;

                        if (progress != null && totalBytes != -1)
                        {
                            progress.Report((totalBytesRead, totalBytes));
                        }
                    }

                    return memoryStream.ToArray();
                }
                catch (Exception ex)
                {
                    lastException = ex;
                    retryCount++;
                    Debug.WriteLine($"下载更新包失败 (尝试 {retryCount}/{MaxRetries}): {ex.Message}");

                    if (retryCount < MaxRetries)
                    {
                        await Task.Delay(RetryDelayMs * retryCount); // 递增延迟
                    }
                }
            }

            throw new Exception($"下载更新包失败，已重试{MaxRetries}次: {lastException?.Message}", lastException);
        }
    }

    public class GiteeReleaseInfo
    {
        [JsonPropertyName("tag_name")]
        public string TagName { get; set; }

        [JsonPropertyName("name")]
        public string Name { get; set; }

        [JsonPropertyName("body")]
        public string Body { get; set; }

        [JsonPropertyName("assets")]
        public GiteeAsset[] Assets { get; set; }

        [JsonPropertyName("created_at")]
        public string CreatedAt { get; set; }
    }

    public class GiteeAsset
    {
        [JsonPropertyName("browser_download_url")]
        public string BrowserDownloadUrl { get; set; }

        [JsonPropertyName("name")]
        public string Name { get; set; }

        [JsonPropertyName("size")]
        public long Size { get; set; }
    }
} 